package org.springframework.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
/**
 * SpringBoot整合了Spring和SpringMVC，底层都是Spring和SpringMVC
 *	为什么 @SpringBootApplication +SpringApplication.run(SpringbootSourceApplication.class, args);能把Spring+SpringMVC+Tomcat+其他场景都整合进来
 *
 * @SpringBootApplication = @SpringBootConfiguration + @EnableAutoConfiguration + @ComponentScan
 *
 * 1) @SpringBootConfiguration ---> @Configuration，代表是容器里的配置类，一个组件 @Configuration配置类会被后置处理器来分析
 * 2) @ComponentScan
 * 3) @EnableAutoConfiguration  ---->
 *
 *       @AutoConfigurationPackage (导入组件) ----> @Import (AutoConfigurationPackages.Registrar.class)
 *       指定我们以后要扫描哪些包，在这些组件里面有一个AutoConfigurationPackages，去看他的BeanDefinition是怎么创建对象进行处理，就可以知道Controller是怎么进行处理的
 *
 *       @Import(AutoConfigurationImportSelector.class) (导入组件) ---->
 *       SpringFactoriesLoader.loadFactoryNames(); 去类路径下找 META-INF/spring.factories文件，
 *       其实就是SPI机制，找到@EnableAutoConfiguration全类名对应的所有配置的值
 *
 *       SpringBoot写好了所有全场景的自动配置类(配置类就是给容器中放组件@Bean)全部导进来，接下来就交给Spring去处理
 */
public class App {

	public static void main(String[] args) {

		/**
		 * SpringBoot.run会创建IOC容器 AnnotationConfigReactiveWebServerApplicationContext
		 * 然后ioc容器启动onRefresh会启动Tomcat
		 * Tomcat启动会加载所有的Servlet
		 * DispatcherServlet会加载九大组件的整个初始化流程
		 *
		 */

		/**
		 *	@see SpringApplication
		 *
		 *
		 */
		//SpringApplication.run(App.class, args);

	}

	/**
	 *  Tomcat和SpringMVC组件的准备过程
	 *   new Tomcat启动 --> 1.利用SPI机制
	 *                     2.自己创建DispatchServlet注册到Tomcat里面(Tomcat有DispatchServlet，启动会调用Servlet初始化，DIspatchServlet在生命周期初始化的时候，初始化九大组件，父子容器等)
	 *   SpringBoot使用第二种
	 *
	 *   Spring底层默认使用的IOC容器是 “ AnnotationConfigServletWebServerApplicationContext ”，IOC容器在刷新的时候需要加载配置类
	 *   组件信息的加载：
	 *      ServletWebServerFactoryAutoConfiguration ----> 搞定ServletWeb服务器
	 *          他引入了4个类：@Import(ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class) web服务器工厂定制化器的后置增强
	 *                      还导入3种不同的服务器：Tomcat、jetty、Undertow，默认是Tomcat的生效
	 *                      对于tomcat：容器中放了TomcatServletWebServerFactory，同时我们自己也可以放一个 ServletWebServerFactory(服务器工厂: 让我们产生并启动服务器)
	 *                             ServletWebServerFactory可以通过 getWebServer() 来创建 Tomcat，同时也准备了ServletContextInitializer
	 *
	 *      DispatchServletAutoConfiguration ------>  搞定SpringMVC
	 *          SpringBoot会通过addServlet之类的方法把自己注册到Tomcat里面
	 *          主要是 DispatcherServletRegistrationBean 这个类，他会把 DispatcherServlet 配置好，并给容器中放好RegistrationBean
	 *          所有的 xxxRegistrationBean 都是允许我们注册原生的Servlet组件进去，然后利用ServletContextInitializer在tomcat启动完成以后进行回调的机制
	 *
	 *   onRefresh: 容器刷新十二大步，在前面的所有组件定义信息进来了，ServletWebServerApplicationContext.onRefresh会做以下事情：
	 *       1.createWebServer() 创建web服务器
	 *       2.拿到前面的Web服务器工厂，调用创建服务器方法ServletWebServerFactory
	 *           2.1 创建Tomcat，封装到TomcatWebServer中
	 *           2.2 定制configureContext(context,initializersToUse【ServletContextInitializer】)回调
	 *           2.3 然后TomcatWebServer创建对象就会启动Tomcat
	 *       3.Tomcat启动的时候要把所有的ServletContextInitializer引入进来
	 *       4.Tomcat启动以后，每一个RegistrationBean就注册进去，DispatcherServlet开始执行整个初始化流程
	 *       5.参照之前的SpringMVC原理即可，父子容器中很多步骤都执行了就只需要执行剩下的操作
	 *
	 */

}
